<template>
  <div
    ref="composite-table"
    class="composite-table"
    :class="{
      'select-none': separatorPress,
    }"
    @mousemove="compositeTableMousemove"
  >
    <div class="flex"
      v-show="options.showSideTree !== undefined ? options.showSideTree : options.sideTreeOptions"
    >
      <ArkSideTree
        v-if="options.sideTreeOptions"
        v-model:options="options.sideTreeOptions"
        class="h-full shrink-0"
        :style="{ width: sideWidth + 'px'}"
      />

      <div
        v-if="options.sideTreeOptions"
        class="separator"
        @mousedown="separatorMousedown"
        @mouseup="separatorMouseup"
      ></div>
    </div>

    <div class="h-full flex flex-col" style="min-width: 0">
      <ArkActionBar
        v-if="options.showActionBar !== undefined ? options.showActionBar : options.actionBarOptions"
        v-model:options="options.actionBarOptions"
      ></ArkActionBar>

      <ArkFilterForm
        v-if="options.showFilterForm !== undefined ? options.showFilterForm : options.filterFormOptions"
        v-model:options="options.filterFormOptions"
        style="border: 1px solid #dcdfe6"
      >
        <template v-for="(slot, slotName) in $slots" #[slotName]="slotProps">
          <slot :name="slotName" v-bind="slotProps"/>
        </template>
      </ArkFilterForm>

      <ArkPaginationTable
        ref="pagination-table"
        v-if="mounted"
        v-model:options="options.tableOptions"
        class="min-w-full flex-1"
      >
        <template v-for="(slot, slotName) in $slots" #[slotName]="slotProps">
          <slot :name="slotName" v-bind="slotProps"/>
        </template>
      </ArkPaginationTable>
    </div>
  </div>
</template>

<script setup lang="ts">
import {computed, onBeforeMount, onMounted, type PropType, ref, useTemplateRef,} from "vue";
import _ from "lodash";
import ArkCompositeTableOptionsDefault, {ArkCompositeTableOptions} from "./ArkCompositeTableOptions";
import ArkSideTree from "../../common/ark-side-tree/ArkSideTree.vue";
import ArkActionBar from "../../common/ark-action-bar/ArkActionBar.vue";
import ArkFilterForm from "../ark-filter-form/ArkFilterForm.vue";
import ArkPaginationTable from "../ark-pagination-table/ArkPaginationTable.vue";

/** 组合（向选项里合并 property）。包括：provide、inject、extends、mixins */

/** 接口（组件的接口）。包括：defineOptions、defineModel、defineProps、defineEmits、defineExpose、defineSlots */
const options = defineModel("options", {
  type: Object as PropType<ArkCompositeTableOptions>,
  default: () => ArkCompositeTableOptionsDefault
});

/** 本地状态 (本地的响应式 property)。包括：ref、computed */
const componentTableRef = useTemplateRef("composite-table");
const paginationTableRef = useTemplateRef("pagination-table");

// 侧边栏相关
const sideWidth = ref(205);
const separatorPress = ref(false);
const separatorStartClientX = ref(0)

// 查询参数相关
const initFetchDataParams = ref({})
const fetchDataParams = computed(() => {
  // 侧边栏查询参数
  const sideFetchDataParams = {}
  const select = options.value.sideTreeOptions.select;
  const selectNode = options.value.sideTreeOptions.selectNode;
  if (
    !_.isNil(options.value.sideTreeOptions)
    && !_.isNil(select)
    && !_.isNil(selectNode)
    && selectNode.length > 0
  ) {
    sideFetchDataParams[select] = selectNode[0].id
  }

  // 过滤栏查询参数
  const filterFetchDataParams = options.value.filterFormOptions?.model ? options.value.filterFormOptions?.model : {};

  return {
    ...initFetchDataParams.value,
    ...sideFetchDataParams,
    ...filterFetchDataParams,
  }
})

const mounted = ref(false);

/** 事件（通过响应式事件触发的回调）。包括：watch */

/** 生命周期钩子（按照它们被调用的顺序）。包括：onBeforeMount、onMounted、onBeforeUpdate、onUpdated、onBeforeUnmount、onUnmounted */
onBeforeMount(() => {
  init();
});

onMounted(() => {
  mounted.value = true;
});

/** 非响应式的 property (不依赖响应系统的实例 property)。包括：常规函数 */
const init = () => {
  _.defaultsDeep(options.value, ArkCompositeTableOptionsDefault);
  initFetchDataParams.value = options.value.tableOptions?.fetchDataParams ? options.value.tableOptions?.fetchDataParams : {}

  handleSectionShowValue();
  handleSectionDefaultAction();
};
const handleSectionShowValue = () => {
  if (_.isNil(options.value.showSideTree)) {
    options.value.showSideTree = options.value.sideTreeOptions !== undefined;
  }

  if (_.isNil(options.value.showActionBar)) {
    options.value.showActionBar = options.value.actionBarOptions !== undefined;
  }

  if (_.isNil(options.value.showFilterForm)) {
    options.value.showFilterForm = options.value.filterFormOptions !== undefined;
  }
};
const handleSectionDefaultAction = () => {
  const tableOptions = options.value.tableOptions;
  if (_.isNil(tableOptions)) {
    return;
  }

  // afterNodeSelectChange：树选中节点改变后，重置分页数据，设置表格数据查询参数并刷新表格数据
  if (!_.isNil(options.value.sideTreeOptions)) {
    options.value.sideTreeOptions.afterNodeSelectChange = (nodes) => {
      // 设置表格数据查询参数
      options.value.tableOptions.fetchDataParams = fetchDataParams.value;

      // 手动刷新表格数据
      if (tableOptions.pagination.pageNumber === 1) {
        paginationTableRef.value.fetchData();
        return;
      }

      // 重置分页数据，ArkPaginationTable内监听分页数据变化并刷新表格数据
      options.value.tableOptions.pagination.pageNumber = 1;
    };
  }

  // filterFormOptions查询操作
  if (
    !_.isNil(options.value.filterFormOptions)
    && !_.isEmpty(options.value.filterFormOptions.actions)
    && !_.isEmpty(options.value.filterFormOptions.actions.confirm)
  ) {
    options.value.filterFormOptions.actions.confirm.beforeClick = () => {
      options.value.tableOptions.fetchDataParams = fetchDataParams.value;
    }
    options.value.filterFormOptions.actions.confirm.afterClick = async (clickReturn) => {
      if (!_.isNil(clickReturn) && clickReturn instanceof Promise) {
        await Promise.resolve(clickReturn);
      }

      // 手动刷新表格数据
      if (tableOptions.pagination.pageNumber === 1) {
        paginationTableRef.value.fetchData();
        return;
      }

      // 重置分页数据，ArkPaginationTable内监听分页数据变化并刷新表格数据
      options.value.tableOptions.pagination.pageNumber = 1;
    }
  }
}

const separatorMousedown = (e) => {
  // 记录起始值
  separatorStartClientX.value = e.clientX;
  separatorPress.value = true;
};
const separatorMouseup = (e) => {
  separatorPress.value = false;
};
const compositeTableMousemove = (e) => {
  window.requestAnimationFrame(() => {
    if (!separatorPress.value) {
      return;
    }

    // 移动距离 = 鼠标位置 - 起始位置
    const moveX = e.clientX - separatorStartClientX.value;
    // 侧边宽度 = 原始宽度 + 移动距离
    const width = sideWidth.value + moveX;

    // 最小宽度限制
    const sideMinWidth = options.value.sideMinWidth;
    if (width < sideMinWidth) {
      sideWidth.value = sideMinWidth;
      separatorStartClientX.value = componentTableRef.value.getBoundingClientRect().x + sideWidth.value;
      separatorPress.value = false;
      return;
    }

    // 最大宽度限制
    const sideMaxWidth = options.value.sideMaxWidth;
    if (width > sideMaxWidth) {
      sideWidth.value = sideMaxWidth;
      separatorStartClientX.value = componentTableRef.value.getBoundingClientRect().x + sideWidth.value;
      separatorPress.value = false;
      return;
    }

    sideWidth.value = width;
    separatorStartClientX.value = e.clientX;
  });
};

/** 其它 */
</script>

<style scoped lang="scss">
.composite-table {
  height: 100%;
  overflow: hidden;
  display: flex;
}

.separator {
  height: 100%;
  width: 5px;
  flex-shrink: 0;
  background-color: #e6eef8;
  cursor: e-resize;
}
</style>
